package com.jwsoft.manager.core.integration.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.alicp.jetcache.Cache;
import com.alicp.jetcache.anno.CacheType;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.annotation.SaveOplog;
import com.bifang.engine.assistant.core.enums.AuTypeEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.cache.jetcache.utils.JetCacheUtils;
import com.bifang.engine.data.core.util.PagerUtil;
import com.bifang.module.base.common.constants.BaseCache;
import com.bifang.module.base.common.util.SignUtil;
import com.bifang.module.base.common.vo.common.CommonVO;
import com.bifang.module.base.core.integration.CommonIntegration;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.common.enums.SchoolNatureEnum;
import com.jwsoft.manager.common.vo.common.AreaControlVO;
import com.jwsoft.manager.common.vo.eduDyjyQuerySync.DySyncResult;
import com.jwsoft.manager.common.vo.eduJhjyQuerySync.EduJhjyQuerySyncVO;
import com.jwsoft.manager.common.vo.eduStudentEnroll.EduStudentEnrollVO;
import com.jwsoft.manager.common.vo.eduSyncJhDelete.EduSyncExistInfo;
import com.jwsoft.manager.common.vo.eduSyncJhDelete.EduSyncJhDeleteQueryVO;
import com.jwsoft.manager.core.dao.model.EduJhjyQuerySync;
import com.jwsoft.manager.core.dao.model.EduStudentEnroll;
import com.jwsoft.manager.core.dao.service.EduStudentEnrollService;
import com.jwsoft.manager.core.util.EduHelper;
import com.jwsoft.manager.core.util.dySync.CallUtils;
import com.jwsoft.manager.core.util.dySync.JsonUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import cn.hutool.core.convert.Convert;

import java.lang.reflect.Field;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import com.bifang.engine.assistant.core.exception.AppException;
import org.springframework.util.ObjectUtils;
import org.springframework.transaction.annotation.Transactional;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.jwsoft.manager.common.vo.eduDyjyQuerySync.EduDyjyQuerySyncVO;
import com.jwsoft.manager.common.vo.eduDyjyQuerySync.EduDyjyQuerySyncKeyVO;
import com.jwsoft.manager.common.vo.eduDyjyQuerySync.EduDyjyQuerySyncQueryVO;
import com.jwsoft.manager.core.integration.EduDyjyQuerySyncIntegration;
import com.jwsoft.manager.core.dao.service.EduDyjyQuerySyncService;
import com.jwsoft.manager.core.dao.model.EduDyjyQuerySync;
import org.springframework.web.bind.annotation.GetMapping;

import javax.xml.transform.Result;

/**
 * 金华录取查询业务实现类
 *
 * @author wangt
 * @since 2024-06-12
 */
@ApiService(funcCode = "eduDyjyQuerySync", title = "金华录取查询")
public class EduDyjyQuerySyncIntegrationImpl implements EduDyjyQuerySyncIntegration {

    @Autowired
    public EduDyjyQuerySyncService eduDyjyQuerySyncService;

    @Autowired
    private EduHelper eduHelper;

    @Autowired
    private CallUtils callUtils;

    @Autowired
    private CommonIntegration commonIntegration;

    @Autowired
    private EduStudentEnrollService eduStudentEnrollService;

    private final String areaCode = "330783";




//    @Value("${xsbm.config.appId}")
//    private String appId;
//
//
//    /**
//     *外部地址请求url
//     */
//    @Value("${xsbm.config.reqUrl}")
//    private String reqUrl;
//    /**
//     * 公钥
//     */
//    @Value("${xsbm.config.appKey}")
//    private String appKey;
//
//    /**
//     * 私钥
//     */
//    @Value("${xsbm.config.appSecret}")
//    private String appSecret;

    @Override
    @OpApi(funcCode = "eduDyjyQuerySync0001", title = "金华录取查询分页查询", funcType = FuncTypeEnum.query,checkPrivilege = BoolEnum.FALSE)
    public PageInfo<EduDyjyQuerySyncVO> getList(EduDyjyQuerySyncQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        PageHelper.startPage(vo.getPageNum(),vo.getPageSize());
        List<EduDyjyQuerySync> list = eduDyjyQuerySyncService.list();
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduDyjyQuerySync> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduDyjyQuerySyncVO> resultList = Convert.toList(EduDyjyQuerySyncVO.class, pageInfo.getList());
        // 转义数据字典值
        // dictHelper.valueToName(resultList, Arrays.asList(DemoDictEnum.values()));
        return PagerUtil.parsePagerVo(resultList, pageInfo);
    }

    @Override
    @OpApi(funcCode = "eduDyjyQuerySync0002", title = "金华录取查询根据主键查询详情", funcType = FuncTypeEnum.query,checkPrivilege = BoolEnum.FALSE)
    public EduDyjyQuerySyncVO getById(EduDyjyQuerySyncKeyVO vo) {
        EduDyjyQuerySync entity = eduDyjyQuerySyncService.getById(vo.getJhjyQueryId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("查询不到详细信息!");
        }
        EduDyjyQuerySyncVO result = Convert.convert(EduDyjyQuerySyncVO.class, entity);
        return result;
    }
    /** 保存前统一校验*/
    @Override
    @OpApi(funcCode = "eduDyjyQuerySync0003", title = "金华录取查询保存前校验", funcType = FuncTypeEnum.other ,checkPrivilege = BoolEnum.FALSE)
    public void checkSave(EduDyjyQuerySyncVO vo) {
        //主键为空为新增校验

        //主键不为空为修改校验
    }

    @Override
    @OpApi(funcCode = "eduDyjyQuerySync0004", title = "金华录取查询新增", funcType = FuncTypeEnum.insert)
    @SaveOplog(
            operationType = "eduDyjyQuerySync0004",
            operationName = "金华录取查询新增",
            dataType = "jhjyQueryId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduDyjyQuerySyncVO add(EduDyjyQuerySyncVO vo) {
        //保存前校验
        checkSave(vo);
        //保存数据
        EduDyjyQuerySync entity = Convert.convert(EduDyjyQuerySync.class, vo);
        eduDyjyQuerySyncService.save(entity);
        //将主键设置回vo使操作日志可以取到
        vo.setJhjyQueryId(entity.getJhjyQueryId());
        return vo;
    }

    @Override
    @OpApi(funcCode = "eduDyjyQuerySync0005", title = "金华录取查询修改", funcType = FuncTypeEnum.update)
    @SaveOplog(
            operationType = "eduDyjyQuerySync0005",
            operationName = "金华录取查询修改",
            dataType = "jhjyQueryId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduDyjyQuerySyncVO edit(EduDyjyQuerySyncVO vo) {
        if (ObjectUtils.isEmpty(vo.getJhjyQueryId())) {
            throw new AppException("传入需要修改的主键不能为空!");
        }
        EduDyjyQuerySync oldEntity = eduDyjyQuerySyncService.getById(vo.getJhjyQueryId());
        if (ObjectUtils.isEmpty(oldEntity)) {
            throw new AppException("查询不到需要修改的信息!");
        }
        //保存前校验
        checkSave(vo);
        //保存数据
        EduDyjyQuerySync entity = Convert.convert(EduDyjyQuerySync.class, vo);
        eduDyjyQuerySyncService.updateById(entity);
        return vo;
    }

    @Override
    @OpApi(funcCode = "eduDyjyQuerySync0006", title = "金华录取查询根据主键删除", funcType = FuncTypeEnum.delete)
    @SaveOplog(
            operationType = "eduDyjyQuerySync0006",
            operationName = "金华录取查询删除",
            dataType = "jhjyQueryId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public void del(EduDyjyQuerySyncKeyVO vo) {
        if (ObjectUtils.isEmpty(vo.getJhjyQueryId())) {
            throw new AppException("传入需要删除的数据主键不能为空!");
        }
        EduDyjyQuerySync entity = eduDyjyQuerySyncService.getById(vo.getJhjyQueryId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("未找到需要删除的信息!");
        }
        eduDyjyQuerySyncService.removeById(vo.getJhjyQueryId());
    }

    @Override
    @OpApi(funcCode = "eduDyjyQuerySync0007", title = "金华市根据类型查询学生信息是否存在",
            funcType = FuncTypeEnum.query, checkPrivilege = BoolEnum.FALSE)
    public EduDyjyQuerySyncVO querySyncInfo(EduStudentEnrollVO vo) {

        checkQuery(vo);

        HashMap<String,Object> params = new HashMap<>();
        params.put("idcard",vo.getIdcard());
        params.put("name",vo.getFullName());


        EduDyjyQuerySync eduDyjyQuerySync = new EduDyjyQuerySync();
        eduDyjyQuerySync.setName(vo.getFullName());
        eduDyjyQuerySync.setIdcard(vo.getIdcard());
        eduDyjyQuerySync.setSchoolCategory(vo.getSchoolCategory());
        eduDyjyQuerySync.setYear(vo.getYear());
        eduDyjyQuerySync.setSyncStatus("0");


        String lqdw = "";
        String type="";
        String accessToken = "";
        Cache<String,String> tokenCache = JetCacheUtils.create(BaseCache.CACHE_ACCESS_TOKEN_CLIENT, CacheType.BOTH, Duration.ofSeconds(1500L),Duration.ofSeconds(60));
        String redisKey=vo.getAreaCode()+vo.getYear();
        accessToken  = tokenCache.get(redisKey);
        if(StringUtils.isBlank(accessToken)){
            //调用获取token方法，得到token信息
            DySyncResult token = this.getToken();
            accessToken = (String) token.getData().get("accessToken");
            tokenCache.put(redisKey,accessToken);
        }

        //map转string
        String paramsStr = JsonUtil.toJsonString(params);

        //将传入参数 进行签名
        String timestamp = String.valueOf(System.currentTimeMillis());


        String appKey = getCommon("dy_sync_appKey");
        String appSecret = getCommon("dy_sync_appSecret");
        String reqUrl = getCommon("dy_sync_reqUrl");
        String appId = getCommon("dy_sync_appId");
        //参数进行加密
        String encrypt = callUtils.encrypt(paramsStr, appKey);
        //解密
//        String decrypt = callUtils.decrypt(encrypt,appSecret);


        //加密传参
        HashMap<String, String> map = new HashMap<>();
        map.put("cryptoStr", encrypt);
        String cryptoStr = JSONObject.toJSONString(map);
        String signature = callUtils.getSign(cryptoStr, appSecret, timestamp);
        if (StringUtils.isBlank(signature)){
            throw new AppException("签名不能为空");
        }
        if (StringUtils.isBlank(accessToken)){
            throw new AppException("accessToken不能为空");
        }


        //调用同步删除接口
        String url = reqUrl+"syncJhQuery0001";
        String data = encrypt;
        HttpResponse execute = HttpRequest.post(url)
                //设置请求体
                .header("Content-Type", "application/json")
                .header("signature", signature)
                .header("timestamp", timestamp)
                .header("accessToken", accessToken)
                .header("appId", appId)
                .setReadTimeout(10000)
//                .body(decrypt) //不加密
                .body(cryptoStr) //加密
                .execute();
        //不加密情况
        String body = execute.body();
        if (StringUtils.isBlank(body)) {
            throw new AppException("请求接口失败失败，未返回信息");
        }
        JSONObject jsonObject = null;
        try {
            jsonObject = JSONObject.parseObject(body);
            if (jsonObject.getInteger("code") != 0) {
                if("401".equals(jsonObject.getString("code"))||"456".equals(jsonObject.getString("code"))){
                    //调用获取token方法，得到token信息
                    DySyncResult token = this.getToken();
                    accessToken = (String) token.getData().get("accessToken");
                    tokenCache.put(redisKey,accessToken);
                }else {
                    String errorMessage = (String)jsonObject.get("message");
                    throw new AppException("错误原因：" + errorMessage);
                }

            }
        }catch (AppException e){
            throw new AppException(e.getMsg());
        }catch (Exception e) {
            throw new AppException("请求接口失败失败：" + body);
        }
        //密文
        String encryptResult = (String) jsonObject.get("result");
        if (StringUtils.isNotBlank(encryptResult)){
            //对密文进行解密
            String decryptResult = callUtils.decrypt(encryptResult, appSecret);
            //解密后的密文转json
            JSONObject jsoncontent = JSONObject.parseObject(decryptResult);

            lqdw = jsoncontent.getString("applyEduName");
            type = jsoncontent.getString("type");
            //转换json
            //jsonBody.put("result", jsoncontent);
            QueryWrapper<EduDyjyQuerySync> querySyncQueryWrapper = new QueryWrapper<>();
            querySyncQueryWrapper.lambda().eq(EduDyjyQuerySync::getIdcard, vo.getIdcard())
                    .eq(EduDyjyQuerySync::getYear, vo.getYear());
            List<EduDyjyQuerySync> list = eduDyjyQuerySyncService.list(querySyncQueryWrapper);

            if (!CollectionUtils.isEmpty(list)) {
                eduDyjyQuerySync.setJhjyQueryId(list.get(0).getJhjyQueryId());
                eduDyjyQuerySync.setCreateName(list.get(0).getCreateName());
                eduDyjyQuerySync.setCreateTime(list.get(0).getCreateTime());
            } else {
                eduDyjyQuerySync.setJhjyQueryId(IdUtil.simpleUUID());
            }
            String lqFlag = BoolEnum.FALSE.getType();
            if (StringUtils.isNotBlank(lqdw)) {
                lqFlag = BoolEnum.TRUE.getType();
            } else {
                lqdw = null;
                type=null;
            }
            eduDyjyQuerySync.setLqDw(lqdw);
            eduDyjyQuerySync.setType(type);
            eduDyjyQuerySync.setSyncStatus("1");
            eduDyjyQuerySync.setSyncRemarks("比对通过");
            CommonVO commonVO = new CommonVO();
            commonVO.setParamKey("localLqDw");
            commonVO.setAreaCode(vo.getAreaCode());
            String localDw = commonIntegration.getValueByKeyAndArea(commonVO);
            if(StringUtils.isBlank(localDw)){
                throw new AppException("请先配置金华教育本地录取单位");
            }
            if (localDw.equals(lqdw)) {
                lqFlag = BoolEnum.FALSE.getType();
                lqdw = null;
            }
            UpdateWrapper<EduStudentEnroll> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().eq(EduStudentEnroll::getIdcard, vo.getIdcard())
                    .eq(EduStudentEnroll::getYear, vo.getYear())
                    .set(EduStudentEnroll::getOtherEnrollUnit, lqdw)
                    .set(EduStudentEnroll::getOtherEnrollStatus, lqFlag);
            eduStudentEnrollService.update(updateWrapper);

        }

        eduDyjyQuerySyncService.saveOrUpdate(eduDyjyQuerySync);
        EduDyjyQuerySyncVO retVO=Convert.convert(EduDyjyQuerySyncVO.class,eduDyjyQuerySync);
        return retVO;
    }

    @Override
    public void createJhjySync(AreaControlVO baseVO) {
        QueryWrapper<EduStudentEnroll> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EduStudentEnroll::getYear, eduHelper.thisYear())
                .eq(StringUtils.isNotBlank(baseVO.getAreaCode()), EduStudentEnroll::getAreaCode, baseVO.getAreaCode())
                .eq(EduStudentEnroll::getSchoolNature, SchoolNatureEnum.gb.getType())
                .isNull(EduStudentEnroll::getOtherEnrollStatus);
        PageHelper.startPage(1, 500);
        List<EduStudentEnroll> list = eduStudentEnrollService.list(queryWrapper);
        PageInfo<EduStudentEnroll> enrollPageInfo = new PageInfo<>(list);
        if (!CollectionUtils.isEmpty(enrollPageInfo.getList())) {
            for (EduStudentEnroll eduStudentEnroll : enrollPageInfo.getList()) {
                EduStudentEnrollVO eduStudentEnrollVO=Convert.convert(EduStudentEnrollVO.class,eduStudentEnroll);
                this.querySyncInfo(eduStudentEnrollVO);
            }
        } else {
            QueryWrapper<EduStudentEnroll> queryMbWrapper = new QueryWrapper<>();
            queryMbWrapper.lambda().eq(EduStudentEnroll::getYear, eduHelper.thisYear())
                    .eq(StringUtils.isNotBlank(baseVO.getAreaCode()), EduStudentEnroll::getAreaCode, baseVO.getAreaCode())
                    .ne(EduStudentEnroll::getSchoolNature, SchoolNatureEnum.gb.getType())
                    .isNull(EduStudentEnroll::getOtherEnrollStatus);
            List<EduStudentEnroll> listMb = eduStudentEnrollService.list(queryMbWrapper);
            if (!CollectionUtils.isEmpty(listMb)) {
                for (EduStudentEnroll eduStudentEnroll : listMb) {
                    EduStudentEnrollVO eduStudentEnrollVO=Convert.convert(EduStudentEnrollVO.class,eduStudentEnroll);
                    this.querySyncInfo(eduStudentEnrollVO);
                }
            }
        }
    }

    private void checkQuery(EduStudentEnrollVO vo) {
        Integer year = eduHelper.thisYear();
        vo.setYear(year);
        if (StringUtils.isBlank(vo.getIdcard())) {
            throw new AppException("证件号码不能为空！");
        }
        if (StringUtils.isEmpty(vo.getFullName())){
            throw new AppException("姓名不能为空！");
        }
    }


    @GetMapping(value = "/getToken")
    public DySyncResult getToken() {
        //去调用外部系统方法 获取token
        HashMap<String, Object> map = new HashMap<>();
        //获取签名
        String timestamp = String.valueOf(System.currentTimeMillis());
        String appKey = getCommon("dy_sync_appKey");
        String appSecret = getCommon("dy_sync_appSecret");
        String reqUrl = getCommon("dy_sync_reqUrl");
        String appId = getCommon("dy_sync_appId");
        String signature = SmUtil.sm3(appId+appKey+appSecret+timestamp).toUpperCase();
        String url = reqUrl + "login0002";
        HttpResponse execute = HttpRequest.post(url)
                //设置请求体
                .header("Content-Type", "application/json")
                .header("signature", signature)
                .header("timestamp", timestamp)
                .header("appId", appId)
                .setReadTimeout(10000)
                .body("{}")
                .execute();
        String body = execute.body();
        if (StringUtils.isBlank(body)) {
            throw new AppException("请求金华教育token失败失败，未返回信息");
        }
        System.out.println(body);
        JSONObject jsonObject = null;
        try {
            jsonObject = JSONObject.parseObject(body);
        } catch (Exception e) {
            throw new AppException("请求金华教育token失败失败：" + body);
        }
        Object refreshToken = JsonUtil.getJsonValue(jsonObject, "refreshToken");
        Object accessToken = JsonUtil.getJsonValue(jsonObject, "accessToken");
        map.put("accessToken",accessToken);
        map.put("refreshToken",refreshToken);
        if(ObjectUtils.isEmpty(accessToken)){
            throw new AppException("请求金华教育token失败失败");
        }
        return DySyncResult.ok().data(map);
    }


    public String getCommon(String param){
        CommonVO commonVO = new CommonVO();
        commonVO.setParamKey(param);
        commonVO.setAreaCode(areaCode);
        String result ="";
        result = commonIntegration.getValueByKeyAndArea(commonVO);
        if (StringUtils.isBlank(result)) {
            throw new AppException("金华教育监管平台接口地址参数未配置！("+param+")");
        }

        return result;
    }

    public  HashMap<String, Object> convertObjectToMap(Object obj)  {
        HashMap<String, Object> map = new HashMap<>();

        Class<?> clazz = obj.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true); // 允许访问私有字段
            String fieldName = field.getName();
            try {
                Object value = field.get(obj);
                map.put(fieldName, value);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            };
        }

        return map;
    }
}
